001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:53:23
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util.overlappers;
010    
011    import EVolve.visualization.*;
012    import EVolve.visualization.Dimension;
013    import EVolve.Scene;
014    import EVolve.util.overlappers.OverlapVisualization;
015    import EVolve.util.unifyutils.Unification;
016    import EVolve.exceptions.NoDataPlotException;
017    import javax.swing.*;
018    import javax.swing.event.*;
019    import java.awt.*;
020    import java.awt.event.*;
021    import java.util.*;
022    
023    public class SynchronousOverlapper extends OverlapVisualization{
024        private final String name = "SynchronousOverlapper";
025        private Visualization overlappedVisualization;
026        private JList availableList,overlappableList;
027        private DefaultListModel modelList;
028        private ArrayList candidates;
029        private boolean shift_ctrl_pressed;
030    
031        public SynchronousOverlapper() {
032            super();
033            colorList = new ArrayList();
034            dialog = null;
035            overlappedVisualization = null;
036            candidates = new ArrayList();
037            modelList = new DefaultListModel();
038            xMax = 0;
039        }
040    
041        public String getName() {
042            return name;
043        }
044    
045        public void createDialog() {
046            shift_ctrl_pressed = false;
047            colorList.clear();
048            visualizationList.clear();
049            modelList.removeAllElements();
050            dialog = new JDialog(Scene.getFrame(), "Overlap Visualizations...", true);
051            dialog.setBounds(new Rectangle(500,400));
052    
053            Box boxMain = new Box(BoxLayout.Y_AXIS);
054            boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
055                    "Choose Visualizations to be overlapped"));
056            dialog.getContentPane().add(boxMain,BorderLayout.CENTER);
057    
058            Box boxLabels = new Box(BoxLayout.X_AXIS);
059            boxLabels.add(new JLabel("Available visualizations:"));
060            boxLabels.add(Box.createHorizontalStrut(130));
061            boxLabels.add(new JLabel("Overlappable visualizations:"));
062    
063            JPanel boxLists = new JPanel(new GridLayout(1,2,25,2));
064            DefaultListModel modelAvail = new DefaultListModel();
065            availableList = new JList(modelAvail);
066            ArrayList arr = Scene.getVisualizationManager().getVisualizationList();
067            for (int i=0; i<arr.size(); i++) {
068                modelAvail.addElement((((Visualization)arr.get(i)).getName()));
069            }
070            availableList.addListSelectionListener(new ListSelectionListener() {
071                public void valueChanged(ListSelectionEvent e){
072                    updateOverlappableList();
073                }
074            });
075    
076            overlappableList = new JList(modelList);
077            overlappableList.addKeyListener(new KeyListener(){
078                public void keyPressed(KeyEvent e) {
079                    if ((e.getKeyCode() == KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_CONTROL)) {
080                        shift_ctrl_pressed = true;
081                    }
082                }
083                public void keyReleased(KeyEvent e) {
084                    if ((e.getKeyCode() == KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_CONTROL)) {
085                        shift_ctrl_pressed = false;
086                    }
087                }
088                public void keyTyped(KeyEvent e) { }
089            });
090            overlappableList.addListSelectionListener(new ListSelectionListener() {
091                public void valueChanged(ListSelectionEvent e){
092                    if ((!shift_ctrl_pressed)&&(!e.getValueIsAdjusting()) && overlappableList.isFocusOwner())
093                        selectColor();
094                }
095            });
096            JScrollPane scrollPane1 = new JScrollPane(availableList);
097            JScrollPane scrollPane2 = new JScrollPane(overlappableList);
098            boxLists.add(scrollPane1);
099            boxLists.add(scrollPane2);
100    
101            boxMain.add(Box.createVerticalStrut(-65));
102            boxMain.add(boxLabels);
103            boxMain.add(Box.createVerticalStrut(-65));
104            boxMain.add(boxLists);
105            boxMain.add(Box.createVerticalStrut(10));
106    
107            Box boxOkCancel = new Box(BoxLayout.X_AXIS);
108            JButton buttonOK = new JButton("OK");
109            JButton buttonCancel = new JButton("Cancel");
110    
111            buttonOK.addActionListener(new ActionListener(){
112                public void actionPerformed(ActionEvent e){
113                    onOK();
114                }
115            });
116            buttonCancel.addActionListener(new ActionListener(){
117                public void actionPerformed(ActionEvent e){
118                    onCancel();
119                }
120            });
121    
122            boxOkCancel.add(Box.createHorizontalStrut(180));
123            boxOkCancel.add(buttonOK);
124            boxOkCancel.add(Box.createHorizontalStrut(20));
125            boxOkCancel.add(buttonCancel);
126    
127            dialog.getContentPane().add(boxOkCancel,BorderLayout.SOUTH);
128            //dialog.setResizable(false);
129        }
130    
131        private void selectColor() {
132            int index = overlappableList.getSelectedIndex();
133    
134            if (index != -1) {
135                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
136                if (newColor != null) {
137                    colorList.add(index+1,newColor);
138                    colorList.remove(index+2);
139                    modelList.removeAllElements();
140                    for (int i=0; i<candidates.size(); i++) {
141                        if (colorList.get(i+1) == null)
142                            modelList.addElement(((Visualization)candidates.get(i)).getName());
143                        else
144                            modelList.addElement("<html><font color=#" + getColorHex((Color)colorList.get(i+1)) + ">"
145                                                 +((Visualization)candidates.get(i)).getName() +" </font></html>" );
146                    }
147                    overlappableList.setSelectedIndex(index);
148                } else {
149                    newColor = Color.black;
150                }
151            }
152        }
153    
154        private void updateOverlappableList() {
155            ArrayList arr = Scene.getVisualizationManager().getVisualizationList();
156            overlappedVisualization = (Visualization)arr.get(availableList.getSelectedIndex());
157    
158            candidates.clear();
159            colorList.clear();
160            overlappableList.removeAll();
161            modelList.removeAllElements();
162            colorList.add(null);
163            for (int i=0; i<arr.size(); i++) {
164                Visualization visual =(Visualization)arr.get(i);
165                if (visual.getVisualizationID() == overlappedVisualization.getVisualizationID()) continue;
166                if (isOverlapable(visual)) {
167                    modelList.addElement(visual.getName());
168                    colorList.add(null);
169                    candidates.add(visual);
170                }
171            }
172        }
173    
174        private void onOK() {
175            int[] indexes = overlappableList.getSelectedIndices();
176            visualizationList.clear();
177    
178            if (indexes.length == 0) {
179                Scene.showErrorMessage("Please select visualizations to be linked");
180                return;
181            }
182    
183            visualizationList.add(overlappedVisualization);
184            for (int i=0; i<indexes.length; i++) {
185                visualizationList.add(candidates.get(indexes[i]));
186            }
187    
188            ArrayList newColorList = new ArrayList();
189            newColorList.add(null);
190            for (int i=0; i<modelList.size(); i++) {
191                for (int j=0; j<indexes.length;j++) {
192                    if (i==indexes[j]) {
193                        newColorList.add(colorList.get(i+1));
194                        break;
195                    }
196                }
197            }
198            colorList = newColorList;
199            dialog.setVisible(false);
200            noEntityAvailable = false;
201    
202            // visualize viz if the user has not visualize them yet
203            ArrayList tobeViz = new ArrayList();
204    
205            for (int i=0; i<visualizationList.size(); i++) {
206                Visualization visual = (Visualization)visualizationList.get(i);
207                AutoImage image = visual.getImage();
208                if (image == null)
209                    tobeViz.add(visual);
210            }
211    
212    
213            if (tobeViz.size() != 0) {
214                int dataSourceId = Scene.getDataSourceManager().getCurrentDataSourceId();
215                for (int i=0; i<tobeViz.size(); i++) {
216                    Visualization visual = (Visualization)visualizationList.get(i);
217                    if (visual.getDataSourceId() != dataSourceId) {
218                        Scene.showErrorMessage("Visualizations belong to different data sources, please\n" +
219                                               "try to first visualize them and then overlap them again.");
220                        return;
221                    }
222                }
223                Scene.getVisualizationManager().prepareForLinkedViz(tobeViz,0);
224                Scene.visualize();
225            }
226    
227            overlappedVisualize();
228        }
229    
230        private void onCancel() {
231            dialog.setVisible(false);
232        }
233    
234        public boolean isOverlapable(Visualization visualToBeOverlapped) {
235            for (int i=0; i<2; i++) {
236                if ((overlappedVisualization.getLinkableDimension(i) == null)||
237                   (visualToBeOverlapped.getLinkableDimension(i) == null))
238                {
239                    if ((overlappedVisualization.getDimension()[i] instanceof ReferenceDimension) ||
240                        visualToBeOverlapped.getDimension()[i] instanceof ReferenceDimension)
241                        return false;
242    
243                    if (!overlappedVisualization.getDimension()[i].getName().equals(visualToBeOverlapped.getDimension()[i].getName()))
244                        return false;
245    
246                } else {
247                    if (overlappedVisualization.getDimension()[i].getDataFilter().getTargetType() !=
248                        visualToBeOverlapped.getDimension()[i].getDataFilter().getTargetType())
249                        return false;
250                }
251            }
252    
253            if ((visualToBeOverlapped.getSubjectDefinition().getName().equals(overlappedVisualization.getSubjectDefinition().getName())) &&
254                (visualToBeOverlapped.getFactory().getName().equals(overlappedVisualization.getFactory().getName())) &&
255                (visualToBeOverlapped.getDataSourceId() == overlappedVisualization.getDataSourceId()))
256                return false;
257    
258            return true;
259        }
260    
261        public void overlappedVisualize() {
262            fullEntitySet = new HashSet[2];
263            fullEntitySet[0] = new HashSet();
264            fullEntitySet[1] = new HashSet();
265    
266            xMax = 0;
267    
268            if (((Visualization)visualizationList.get(0)).getDimension()[0] instanceof ReferenceDimension)
269                Unification.getUnifiedEntity(fullEntitySet[0],visualizationList,0);
270            if (((Visualization)visualizationList.get(0)).getDimension()[1] instanceof ReferenceDimension)
271                Unification.getUnifiedEntity(fullEntitySet[1],visualizationList,1);
272    
273    
274            if (window instanceof EVolve.Window) {
275                Scene.getUIManager().removeWindow(window);
276                window = null;
277            }
278    
279            unifyVisualizations();
280    
281            newOverlappedVisualization(this);
282    
283            sort();
284            enableSortMenu();
285        }
286    
287        private void unifyVisualizations() {
288    
289            for (int i=0; i<visualizationList.size(); i++) {
290                Visualization visual = (Visualization)visualizationList.get(i);
291    
292                Color newColor = (Color)colorList.get(i);
293                Unification.changeColor(visual.getImage(),newColor);
294    
295                for (int j=0; j<fullEntitySet.length; j++) {
296                    Dimension dim = visual.getDimension()[j];
297                    if (fullEntitySet[j].size() > 0) {
298                        ((ReferenceDimension)dim).linkEntities(fullEntitySet[j]);
299                        try {
300                            ((ReferenceDimension)dim).visualize();
301                        } catch (NoDataPlotException e) {
302                            Scene.showErrorMessage(e.getMessage());
303                        }
304                    }
305                }
306            }
307        }
308    }